package com.snda.sc.web;

import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.HttpRequestHandler;

import com.snda.sc.store.IRedisStore;
import com.snda.sc.utils.Constants.ResultCode;
import com.snda.sc.utils.Keys;
import com.snda.sc.utils.Logs;

@Component("checkCodeServlet")
public class CheckCodeServlet implements HttpRequestHandler {

	@Value("${sc.plt}")
	private String plt;
	@Resource(name = "redisStore")
	private IRedisStore redisStore;

	@Override
	public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		response.setContentType("text/plain;charset=UTF-8");

		String appId = request.getParameter("appid");
		String code = request.getParameter("code");
		String uid = request.getParameter("uid");

		PrintWriter out = response.getWriter();
		int result = ResultCode.CK_OK;
		if (!StringUtils.hasLength(appId) || !StringUtils.hasLength(code) || !StringUtils.hasLength(uid)) {
			result = ResultCode.CK_ERR_PARAMATER;
		} else {
			result = checkCode(plt, code, uid);
		}

		out.write("" + result);
		out.flush();

		String clientIp = request.getRemoteAddr();
		if (result == ResultCode.CK_OK) {
			Logs.logCheckCodeInfo("CheckCode successfully. Request: plt={}, appId={}, code={}, uid={} from client:{}.", plt,
					appId, code, uid, clientIp);
		} else {
			Logs.logCheckCodeInfo(
					"CheckCode failure for resultCode: {}. Request: plt={}, appId={}, code={}, uid={} from client:{}.",
					result, plt, appId, code, uid, clientIp);
		}
	}

	private int checkCode(String plt, String code, String uid) {
		String uidKey = Keys.uidKey(plt, code);
		String ticketKey = Keys.ticketKey(plt, uid);

		String uidActual = null;
		String ticket = null;
		try {
			uidActual = redisStore.get(uidKey);
			ticket = redisStore.get(ticketKey);

			if (uidActual == null) return ResultCode.CK_ERR_CODE_EXPIRES;
			if (ticket == null) return ResultCode.CK_ERR_TICKET;
			if (!uidActual.equals(uid)) return ResultCode.CK_ERR_UID_DIF;

			redisStore.del(Keys.ticketKey(plt, uidActual));
		} catch (Exception e) {
			Logs.logException("CheckCode read redis error.", e);
			return ResultCode.CK_ERR_REDIS;
		}

		String codeActual = Keys.newCode(uid, ticket);
		if (!codeActual.equals(code)) return ResultCode.CK_ERR_CODE_FAIL;
		return ResultCode.CK_OK;
	}
}
